# -*-coding:utf-8 -*-
from core.models import *
from .serializers import *
import re
from datetime import datetime
from rest_framework.decorators import api_view, permission_classes
from django.http import Http404
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework import status, renderers, permissions
from rest_framework_gis.pagination import GeoJsonPagination
from rest_framework_gis.filters import InBBoxFilter, TMSTileFilter, DistanceToPointFilter
from rest_framework import generics, parsers
from rest_framework import mixins
from django.conf import settings
from rest_framework.permissions import IsAuthenticated
from rest_framework.exceptions import ValidationError
from django.views.decorators.cache import cache_page
from rest_framework.authtoken.views import ObtainAuthToken
from rest_framework.authtoken.models import Token
from django.db.models.query_utils import Q
from rest_framework import viewsets
from django_filters import rest_framework as filters
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.views.decorators.debug import sensitive_post_parameters
from django.apps import apps
sensitive_post_parameters_m = method_decorator(
    sensitive_post_parameters(
        'password', 'old_password', 'new_password1', 'new_password2'
    )
)


class UserContext(object):
    children_depids = None
    parents_ids = None
    personnel = None
    department = None

    def has_view_all_permission(self, model=None):
        if model is None:
            return False
        viewall_codename = get_permission_codename('viewall', model._meta)

        self.user.has_perm('%s.%s' % (self.app_label, viewall_codename))

    def init_userContext(self):
        self.personnel = self.request.user.personnel
        self.department = getattr(self.personnel, "department", None)
        children_ids_key = "children_ids_%s" % self.request.user.id
        parents_ids_key = "parents_ids_%s" % self.request.user.id
        self.children_depids = cache.get(children_ids_key, None)
        if self.children_depids is None:
            mcls = apps.get_model(app_label="org", model_name="department")
            self.children_depids = mcls.objects.children_ids(self.department.id)
            cache.set(children_ids_key, self.children_depids)

        self.parents_ids = cache.get(parents_ids_key, None)
        if self.parents_ids is None:
            mcls = apps.get_model(app_label="org", model_name="department")
            self.parents_ids = mcls.objects.parents_ids(self.department.id)
            cache.set(parents_ids_key, self.parents_ids)

    def initial(self, request, *args, **kwargs):
        super(UserContext, self).initial(request, *args, **kwargs)
        self.init_userContext()


class HtmlApiMixin(object):
    renderer_classes = (renderers.BrowsableAPIRenderer, renderers.TemplateHTMLRenderer, renderers.JSONRenderer)
    title = "KMS"
    description = None
    site_title = getattr(settings, 'SITE_TITLE', u"MOBILE API")
    site_keywords = getattr(settings, 'SITE_KEYWORDS', u"KMS")

    template_name = None
    detail_template_name = None
    list_template_name = None
    more_template_name = None

    def get_html_context(self):
        context = {}
        try:
            context['is_abrowser'] = self.request._request.META['HTTP_USER_AGENT'].startswith("7BYTE/ABrowser")
        except:
            context['is_abrowser'] = False
        context['site_title'] = self.site_title
        context['site_keywords'] = self.site_keywords
        context['site_description'] = u""
        context["title"] = self.title
        context["description"] = self.description
        return context


class HtmlModelViewSet(viewsets.ModelViewSet, HtmlApiMixin):
    renderer_classes = (renderers.BrowsableAPIRenderer, renderers.TemplateHTMLRenderer, renderers.JSONRenderer)

    def list(self, request, *args, **kwargs):
        if request.accepted_renderer.format == 'html':
            self.template_name = self.list_template_name
            queryset = self.filter_queryset(self.get_queryset())
            objects = self.paginate_queryset(queryset)
            context = self.get_html_context()
            context['paginator'] = self.paginator
            if objects:
                context['is_paginated'] = True
                context['objects'] = objects
                context['page_obj'] = self.paginator.page
                context['next_link'] = self.paginator.get_next_link()
                context['previous_link'] = self.paginator.get_previous_link()
            else:
                context['objects'] = queryset
            if request.query_params.get('_ajax', None):
                self.template_name = self.more_template_name
                context.update({'is_ajax': True})
            return Response(context)
        return super(HtmlModelViewSet, self).list(request, *args, **kwargs)

    def retrieve(self, request, *args, **kwargs):
        self.template_name = self.detail_template_name
        if request.accepted_renderer.format == 'html':
            context = self.get_html_context()
            context['object'] = self.get_object()
            return Response(context)
        return super(HtmlModelViewSet, self).retrieve(request, *args, **kwargs)


class DynamicFieldsViewMixin(object):
    def get_serializer(self, *args, **kwargs):

        serializer_class = self.get_serializer_class()

        fields = None
        if self.request and self.request.method == 'GET':
            query_fields = self.request.query_params.get("fields", None)

            if query_fields:
                fields = tuple(query_fields.split('.'))

        kwargs['context'] = self.get_serializer_context()
        kwargs['fields'] = fields
        return serializer_class(*args, **kwargs)
class ObtainAuthTokenView(ObtainAuthToken):
    """
    
    Token认证信息

    """
    renderer_classes = (renderers.JSONRenderer, renderers.BrowsableAPIRenderer)

    def post(self, request, format=None):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)
        # userprofile = user.userprofile
        result = {
            'token': token.key,
            'user_id': user.id,
            'profile_id': None,
            'licensed_to': getattr(settings, 'LICENSED_TO', u"未授权"),
        }
        try:
            due_date_str = getattr(settings, "DUE_DATE", None)
            due_date = datetime.strptime(due_date_str, "%Y-%m-%d")
            result['is_due'] = datetime.today() > due_date
        except:
            result['is_due'] = True

        svr_urls = {
            "NOTIFY_BROKER": getattr(settings, "NOTIFY_BROKER", None)
        }
        USR_SVR_ROLE = getattr(settings, "USR_SVR_ROLE", {})
        svr_urls.update(USR_SVR_ROLE)

        if svr_urls.get("ADMIN", None) is None:
            try:
                adminindex = reverse("xadmin:index")
            except:
                adminindex = "/admin/"
            svr_urls["ADMIN"] = request.build_absolute_uri(adminindex)
        try:
            apiindex = reverse("restdocs:index")
        except:
            apiindex = "/api/"
        if svr_urls.get("API", None) is None:
            svr_urls["API"] = request.build_absolute_uri(apiindex)
        if svr_urls.get("PUB_API", None) is None:
            svr_urls["PUB_API"] = request.build_absolute_uri(apiindex)
        result.update(svr_urls)
        CURRENT_SVT_ROLE = getattr(settings, "CURRENT_SVT_ROLE", None)
        if CURRENT_SVT_ROLE == 'PUB_API':  # 共享接口
            result.pop('ADMIN')
            result.pop('API')
            result.pop('NOTIFY_BROKER')
        
        result.update(request.COOKIES)
        return Response(result)


class PasswordChangeView(GenericAPIView):
    """
    #密码修改#

    Accepts the following POST parameters: new_password1, new_password2
    Returns the success/fail message.
    """
    serializer_class = PasswordChangeSerializer
    permission_classes = (IsAuthenticated,)

    @sensitive_post_parameters_m
    def dispatch(self, *args, **kwargs):
        return super(PasswordChangeView, self).dispatch(*args, **kwargs)

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response({"detail": u"新的密码已经设置。"})


@api_view(['GET'])
def cookies(request, format=None):
    """
    获取 COOKIE
    """
    if request.method == 'GET':
            return Response(request.COOKIES)




